current version 1.0 - 1st July 2018
version | date | comment |
---|---|---|
1.0 | 01/Jul/2018 | Original code |
license: GNU GPL http://www.gnu.org/licenses/
routines to implement Kriging interpolation. Firstly the
semivariogram is generated from a given sample.
The sample point pairs are ordered into even-width bin,
separated by the euclidean distance of the point pairs.
The Semivariance in the bin is calculated by the Matheron estimator.
If number of lags and lag max distance are not given
they are automatically computed or set to default value.
Empirical semivariogram is then automatically fitted
to the best fitting model among Spherical, Exponential,
Gaussian, and Power, considering the nugget effect.
Fitting algorithm is adapted from the VARFIT model
by Pardo-Iguzquiza (1999). The VARFIT algorithm
performs a nonlinear minimization of the weighed
squared differences between the experimental
variogram and the model. The weighting function
is the inverse of the estimation variance.
VARFIT uses a non-linear minimisation method
that does not require (explicit) initial values for the
parameters in order to initialise the minimisation al-
gorithm. Jian et al. (1996) report problems with con-
vergence if the initial guess is poor.
Solution is found with the simplex method of function
minimization of Nelder and Mead (1965)
This ingenious method is efficient for non-linear mini-
mization in a multiparameter space but is still easy to
program and only requires evaluations of the objective
function. The program stops the iterations whenever
one of the two following criteria is reached:
1. Convergence is reached
2. The maximum number of iterations is reached.
The best fitted semivariogram model is used
to interpolate a regular grid of data.
Code is adapted from the Geostats program
written by Luke Spadavecchia, Biosphere Atmosphere
Modelling Group, University of Edinburgh, November 2006.
A number of closest points are used to buils
the covariance matrix used to predict value at
location where value is unknown. Matrix inversion
uses the the Gauss-Jordan method.
An n*2,n work array is assembled, with the array
of interest on the left half, and the identity matrix
on the right half. A check is made to ensure the matrix is
invertable, and the matrix inverse is returned, providing
the matrix is not singular. The matrix is invertable if,
after pivoting and row reduction, the identity matrix
shifts to the left half of the work array.
References:
Pardo-Iguzquiza, E. VARFIT: a fortran-77 program for fitting variogram models by weighted least squares. Computers & Geosciences, 25, 251-261, 1999.
Nelder, J.A., Mead, R., 1965. A simplex method for function minimization. Computer Journal 7, 308-313.
Jian, X., Olea, R.A., Yu, Y., 1996. Semivariogram modelling by weighted least squares. Computers & Geosciences 22 (3), 387-397.
Type | Visibility | Attributes | Name | Initial | |||
---|---|---|---|---|---|---|---|
integer, | public, | parameter | :: | AUTOFIT | = | 5 |
automatic fitting among spherical, exponential and gaussian |
integer, | public, | parameter | :: | EXPONENTIAL | = | 2 |
fit exponential semivariogram model |
integer, | public, | parameter | :: | GAUSSIAN | = | 3 |
fit gaussian semivariogram model |
integer, | public, | parameter | :: | POWER | = | 4 |
fit power semivariogram model |
integer, | public, | parameter | :: | SPHERICAL | = | 1 |
fit spherical semivariogram model |
type(pairs), | public, | DIMENSION (:,:), ALLOCATABLE | :: | hobs | |||
real(kind=float), | private | :: | anisotropyAngle |
anisotropy angle |
|||
real(kind=float), | private | :: | anisotropyRatio |
anisotropy ratio >= 1 |
|||
type(site), | private, | DIMENSION (:), ALLOCATABLE | :: | controlpts |
subset of closest points used for interpolation |
||
real(kind=float), | private, | DIMENSION (:), ALLOCATABLE | :: | cvest | |||
real(kind=float), | private, | DIMENSION (:,:), ALLOCATABLE | :: | cvobs | |||
real(kind=float), | private, | ALLOCATABLE | :: | dir(:) |
angle (radians) between the direction of the variogram and the x axis, measured from the x axis anti-clockwise |
||
real(kind=float), | private, | ALLOCATABLE | :: | dir_pairs(:,:) |
direction angle between pairs |
||
real(kind=float), | private, | ALLOCATABLE | :: | dist(:,:) |
average distance for each direction and lag RIMETTERE PRIVATE |
||
real(kind=float), | private, | ALLOCATABLE | :: | dist_pairs(:,:) |
distance between pairs |
||
real(kind=float), | private, | ALLOCATABLE | :: | empVariogram(:,:) |
experimental (empirical) variogram for each direction and lag !RIMETTERE PRIVATE |
||
real(kind=float), | private | :: | expVar |
experimental variance |
|||
real(kind=float), | private, | DIMENSION (:), ALLOCATABLE | :: | hest | |||
real(kind=float), | private | :: | hfina |
value of the objective function at the minimum |
|||
integer(kind=short), | private | :: | ieva | ||||
integer(kind=short), | private | :: | ipara |
number of parameters to estimate |
|||
integer(kind=short), | private, | ALLOCATABLE | :: | lagNumber(:) |
number of lags for each direction |
||
real(kind=float), | private | :: | lagTolerance(4) |
How much the distance between pairs can differ from the exact lag distance and still be included in the lag calculations (m) |
|||
integer(kind=short), | private, | DIMENSION(:), ALLOCATABLE | :: | last | |||
integer(kind=short), | private | :: | minpairs | = | 30 |
minimum number of pairs in the lag to be considered valid for semivariogram fitting. |
|
real(kind=float), | private, | ALLOCATABLE | :: | modVariogram(:,:) |
modelled (empirical) variogram for each direction and lag !RIMETTERE PRIVATE |
||
integer(kind=short), | private | :: | ndir |
number of directions of the variogram |
|||
integer(kind=short), | private | :: | npep | ||||
real(kind=float), | private | :: | nugget |
nugget effect (C0) |
|||
integer(kind=short), | private | :: | nvar | ||||
integer(kind=short), | private | :: | objectiveFunction |
kind of objective function to minimize |
|||
type(pairs), | private, | DIMENSION (:,:), ALLOCATABLE | :: | obsdist |
distance matrix |
||
integer(kind=short), | private, | ALLOCATABLE | :: | pairNumber(:,:) |
number of pairs for each direction and lag |
||
real(kind=float), | private | :: | parRangeMax(5) |
maximum values of parameters |
|||
real(kind=float), | private | :: | parRangeMin(5) |
minimum values of parameters |
|||
real(kind=float), | private | :: | partialSill |
partial sill (C1) sill of the variogram |
|||
real(kind=float), | private | :: | range |
range |
|||
real(kind=float), | private | :: | var |
variance |
|||
real(kind=float), | private, | DIMENSION (:), ALLOCATABLE | :: | weights |
Type | Visibility | Attributes | Name | Initial | |||
---|---|---|---|---|---|---|---|
real(kind=float), | public | :: | h |
pair distance |
|||
integer(kind=short), | public | :: | p1 |
id of points pair |
|||
integer(kind=short), | public | :: | p2 |
id of points pair |
|||
real(kind=float), | public | :: | theta |
pair angle |
Type | Visibility | Attributes | Name | Initial | |||
---|---|---|---|---|---|---|---|
real(kind=float), | public | :: | h |
distance (m) |
|||
integer(kind=short), | public | :: | oid |
identification code |
|||
real(kind=float), | public | :: | theta |
anistropy angle |
|||
real(kind=float), | public | :: | value |
observed value |
|||
type(Coordinate), | public | :: | xyz |
position |
function called by Simplex
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
real(kind=float), | intent(in) | :: | b(:) | |||
integer(kind=short), | intent(in) | :: | ipara |
function called by Simplex
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
real(kind=float), | intent(in) | :: | a(:) | |||
integer(kind=short), | intent(in) | :: | varmodel |
Interpolate irregularly spaced data using Kriging. The subroutine generates an empirical semivariogram (anisotropy is assumed), fits the best model among spherical, exponential and gaussian.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(ObservationalNetwork), | intent(in) | :: | sitedata | |||
integer(kind=short), | intent(in) | :: | anisotropy |
if = 1, anisotropy is considered |
||
integer(kind=short), | intent(in) | :: | nlags |
the number of discrete distances used for comparing data, if 0 it is set to default value |
||
real(kind=float), | intent(in) | :: | maxlag |
maximum distance to consider for semivariogram assessment (m), if 0 it is automatically computed |
||
integer(kind=short), | intent(in) | :: | neighbors |
number of neighbors to consider for interpolation |
||
integer(kind=short), | intent(in) | :: | varModel |
semivariogram model, autofit for atomatic selecting the best among spherical, exponential, and gaussian |
||
type(grid_real), | intent(inout), | optional | :: | grid |
interpolated grid |
|
type(grid_real), | intent(inout), | optional | :: | gridvar |
variance of interpolated grid |
|
type(Coordinate), | intent(in), | optional | :: | points(:) |
list of coordinates for prediction (alternative to regular grid) |
|
real(kind=float), | intent(inout), | optional, | DIMENSION (:) | :: | predictions | |
real(kind=float), | intent(inout), | optional, | DIMENSION (:) | :: | predictionsVar |
A generic subroutine to invert a square 2D matrix by pivoting ("Gauss-Jordan" method). An n*2,n work array is assembled, with the array of interest on the left half, and the identity matrix on the right half. A check is made to ensure the matrix is invertable, and the matrix inverse is returned, providing the matrix is not singular. The matrix is invertable if, after pivoting and row reduction, the identity matrix shifts to the left half of the work array. Initially the code was written in integer form to avoid fractions in the work array, but numbers rapidly become inconcevably large. The implemented solution therefore works on fractional pivot rows, with pivots factored to leading ones. Double precision arrays have been used to maintain numerical stability.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
real(kind=float), | intent(in), | DIMENSION(:,:) | :: | input | ||
real(kind=float), | intent(out), | DIMENSION(:,:) | :: | output |
Compute direction angle between pairs (radians) measured from the x axis anti-clockwise
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(ObservationalNetwork), | intent(in) | :: | stations |
Subroutine to calculate a covariance vector from a semivariogram model and a vector of separation distances.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
real(kind=float), | intent(in), | DIMENSION(:) | :: | dist |
separation distance vector |
|
real(kind=float), | intent(in), | DIMENSION(:) | :: | theta |
anisotropy angle ?? |
|
real(kind=float), | intent(out), | DIMENSION(:) | :: | cov |
covariance vector |
|
real(kind=float), | intent(in) | :: | sill |
partial sill (total sill - nugget) from automatic fitting |
||
real(kind=float), | intent(in) | :: | range |
range from automatic fitting |
||
integer(kind=short), | intent(in) | :: | varmodel |
semivariogram model: 1 = spherical, 2 = exponential, 3 = gaussian, 4 = power |
Subroutine to calculate a covariance matrix of observations from a semivariogram model and a vector of separation distances.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
real(kind=float), | intent(in), | DIMENSION(:,:) | :: | dist |
separation distance vector |
|
real(kind=float), | intent(in), | DIMENSION(:,:) | :: | theta |
anisotropy angle ?? |
|
real(kind=float), | intent(out), | DIMENSION(:,:) | :: | cov |
covariance matrix |
|
real(kind=float), | intent(in) | :: | sill |
partial sill (total sill - nugget) from automatic fitting |
||
real(kind=float), | intent(in) | :: | range |
range from automatic fitting |
||
integer(kind=short), | intent(in) | :: | varmodel |
semivariogram model: 1 = spherical, 2 = exponential, 3 = gaussian, 4 = power |
A subroutine to assemble the global distance. This operation is only carried out once; kriging observations matricies are subsetted from this lookup table to speed up processing.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(ObservationalNetwork), | intent(in) | :: | stations |
evaluation of the objective function
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
integer(kind=short), | intent(in) | :: | varmodel | |||
real(kind=float), | intent(out) | :: | hoo |
A subroutine to predict the data value of an unsampled location, using geostatistical methods. Interpolation is carried out using the 'Ordinary Kriging' method.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
real(kind=float), | intent(in), | DIMENSION(:,:) | :: | cvobs | ||
real(kind=float), | intent(in), | DIMENSION(:) | :: | cvest | ||
real(kind=float), | intent(in), | DIMENSION(:) | :: | controlpts | ||
real(kind=float), | intent(out) | :: | est |
estimated value |
||
real(kind=float), | intent(out) | :: | var |
variance of estimated value |
||
integer(kind=short), | intent(in) | :: | neighbors | |||
real(kind=float), | intent(in) | :: | sill |
Initialize variables for kriging
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
integer(kind=short), | intent(in) | :: | anisotropy |
if = 1, anisotropy is considered |
||
integer(kind=short), | intent(in) | :: | nlags |
the number of discrete distances used for comparing data, if 0 it is set to default value |
||
real(kind=float), | intent(in) | :: | maxlag |
maximum distance to consider for semivariogram assessment (m), if 0 it is automatically computed |
||
integer(kind=short), | intent(in) | :: | count |
total number of available observations |
||
integer(kind=short), | intent(in) | :: | neighbors |
number of neighbors to consider for interpolation |
||
integer(kind=short), | intent(out) | :: | nclosest |
Compute distance between pairs
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(ObservationalNetwork), | intent(in) | :: | stations |
generate a Semivariogram from a given sample. The sample point pairs are ordered into even-width bin, separated by the euclidean distance of the point pairs. The Semivariance in the bin is calculated by the Matheron estimator. If number of lags and lag max distance are not given they are automatically computed or set to default value.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(ObservationalNetwork), | intent(in) | :: | stations |
Subroutine to find the distances between prediction point and observations. Also returns angles if anisotropy present
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(site), | intent(in) | :: | prediction | |||
type(ObservationalNetwork), | intent(in) | :: | observations | |||
type(site), | intent(out), | DIMENSION(:) | :: | estdist |
This subroutine implements the simplex method of function minimization of Nelder and Mead (1965). This ingenious method is efficient for non-linear mini- mization in a multiparameter space but is still easy to program and only requires evaluations of the objective function. The program stops the iterations whenever one of the two following criteria is reached: 1. Convergence is reached 2. The maximum number of iterations is reached.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
integer(kind=short), | intent(in) | :: | varModel |
type of variogram: 1 = spherical, 2 = exponential, 3 = gaussian, 4 = power |
Subroutine to sort a vector of points using the Heap-sort algorithm. Data are sorted by value if flag =1, or by separation distance if flag = 0. Actually, only a pointer is sorted, as this is more efficient. Subroutine Adapted from Numerical Recipes in Fortran 90: Press, Teukolsky, Vetterling and Flannery (1996) pg. 1171
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(site), | intent(inout), | DIMENSION(:) | :: | input | ||
integer, | intent(in) | :: | flag |
A subroutine to retrieve the nearest neighbors of the estimation location referred to as control points. The observations separation matrix is returned (as a precursor to producing the observations covariance matrix) along with the vector of nearest neighbbors.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(site), | intent(inout), | DIMENSION(:) | :: | estdist | ||
integer(kind=short), | intent(in) | :: | neighbors |
Fit model to experimental variogram
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
integer(kind=short), | intent(in) | :: | varModel | |||
integer(kind=short), | intent(out) | :: | modelselected |
if automodel is passed as varModel, the optimal model is returned |
calculation of the variogram value in 2D
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
integer(kind=short), | intent(in) | :: | varmodel | |||
real(kind=float), | intent(inout) | :: | h | |||
real(kind=float), | intent(in) | :: | alpha | |||
real(kind=float), | intent(out) | :: | gam |